#include "LPC11xx.h"
#include "timer32.h"
#include "uart.h"
#include "gpio.h"

/***************************************************************
 * Macro definitions                                           *
 ***************************************************************/

/***************************************************************
 * Globol variables                                            *
 ***************************************************************/
//extern volatile uint32_t UARTCount;
//extern volatile uint8_t UARTBuffer[BUFSIZE];

#define HEADER  0x0
static volatile uint8_t serialNumber;

/***************************************************************
 * Functions                                                   *
 ***************************************************************/
void updateSerialNumber()
{
    uint32_t i;

    serialNumber = (uint8_t) HEADER << 4;
    for (i = 0; i < 4; i++)
    {
        serialNumber |= (uint8_t) (GPIOGetValue(3, i) << i);
    }
}

void myGPIOIntFunc(void * IR)
{
     updateSerialNumber();
}

//void myTimerIntFunc(void * IR)
//{
//    if ( *(uint32_t*)IR & 0x01 )
//    {
//        GPIOSetValue(PORT2, 7, !GPIOGetValue(2, 7));
//    }
//}


void myDelay (uint32_t ulTime)
{
    uint32_t i;

    i = 0;
    while (ulTime--) {
        for (i = 0; i < 5000; i++);
    }
}

/***************************************************************
 * MAIN                                                        *
 ***************************************************************/
int main (void)
{
//    uint32_t const UART_SEND_LEN = 17;
//    uint8_t UARTStr[UART_SEND_LEN] = "UART TEST OK!!!\r\n";
    uint8_t i;


    SystemInit();             /* MUST BE INCLUDED! */

    GPIOInit();
    // LED
    GPIOSetDir(2, 7, GPIO_DIR_OUTPUT);
    // serial number switches.
    for (i = 0; i < 4; i++)
    {
        GPIOSetDir(PORT3, i, GPIO_DIR_INPUT);
//        /* Set port 3.0 to up/down-edge interrupt. */
//        GPIOSetInterrupt(PORT3, i, 0, 0, 0);
//        GPIOSetInterrupt(PORT3, i, 0, 0, 1);
//        GPIOIntEnable(PORT3, i);
    }

    GPIOSetIntCallback(3, myGPIOIntFunc);
    // set pull-up resistor enable.
    // in this case, the switches can connected to VCC.
    // and the level of IO pins stand for the serial number
    // (no need to do NON operation).
    LPC_IOCON->PIO3_0 |= (0x1 << 4);
    LPC_IOCON->PIO3_1 |= (0x1 << 4);
    LPC_IOCON->PIO3_2 |= (0x1 << 4);
    LPC_IOCON->PIO3_3 |= (0x1 << 4);

//    /* Set port 3.0 to down-edge interrupt. Last parament is useless. */
//    GPIOSetInterrupt(PORT3, 0, 0, 0, 0);
//    GPIOIntEnable(PORT3, 0);
//    GPIOSetIntCallback(3, myGPIOIntFunc);

//    /* Set a timer to call interrupt per second. */
//    Timer32Init(TIMER32_0, 3000 * (SystemAHBFrequency / 1000));
//    Timer32SetIntCallback(TIMER32_0, myTimerIntFunc);
//    Timer32Enable(TIMER32_0);

    /* Uart test */
    UARTInit(600);
//    myDelay(10);
//    UARTSend(UARTStr, UART_SEND_LEN);     // send message.


    // updata serial number from switches first.
    updateSerialNumber();

    while (1) {
//        if ( UARTCount != 0 )
//        {
//            LPC_UART->IER = IER_THRE | IER_RLS;			/* Disable RBR */
//            UARTSend( (uint8_t *)UARTBuffer, UARTCount );
//            UARTCount = 0;
//            LPC_UART->IER = IER_THRE | IER_RLS | IER_RBR;	/* Re-enable RBR */
//        }
//		else {
			updateSerialNumber();
	        UARTSend(&serialNumber, 1);     // send message.
			myDelay(200/LPC_SYSCON->SYSAHBCLKDIV);
            // blinky LED.
            GPIOSetValue(2, 7, !GPIOGetValue(2, 7));
//		}				   
    }
}

/***************************************************************
 * END OF FILE                                                 *
 ***************************************************************/
